import 'dart:typed_data';

import 'package:bluetooth_protocols_plugin/src/base/realtime/realtime_status_base.dart';
import 'package:bluetooth_protocols_plugin/src/tools/bit_utils.dart';
import 'package:bluetooth_protocols_plugin/src/tools/utils.dart';

/*
  typedef ARM_PACKED struct{
    uint32_t hmic_run_mode      : 3; //0 失能状态         1 工作状态
                                     //2 休眠状态         3 锁车状态
    uint32_t mc_run_mode        : 3; //0 正常失能状态     1 正常平衡状态
                                     //2 保护翘板状态     3 保护失能状态
                                     //4 电机锁死状态     5 空载保护状态
                                     //6 负载检测状态     7 辅助平衡状态
    uint32_t motor_work         : 1; //0 电机在非工作状态 1 电机在工作状态
    uint32_t charge_state       : 1; //0 非充电状态       1 充电状态
    uint32_t backup_battery     : 1; //0 备用电池未接入   1 备用电池已接入
    uint32_t charge_port_detect : 3; //0 无任何设备接入     1 充电器插入   2 备用电池输出口插入  3 另一台车的直流输出口接入  4 不能识别的设备

    uint32_t charge_port_on     : 1; //0 充电口关闭状态     1 充电口开启状态
    uint32_t dc_port_detect     : 3; //0 无任何设备接入     1 逆变器插入   2 备用电池充电口插入  3 另一台车的充电口接入  4 不能识别的设备
    uint32_t dc_output_enable   : 1; //0 直流输出口关闭     1 直流输出口开启
    uint32_t lamp_state         : 1; //0 照明灯关闭状态   1 照明灯开启状态
    uint32_t decorative_light   : 1; //0 装饰灯关闭状态   1 装饰灯开启状态
    uint32_t lifted             : 1; //0 提手未触发状态   1 提手触发状态
    uint32_t tail_light         : 3; //0 尾灯关闭状态
                                     //1 尾灯低亮状态
                                     //2 尾灯高亮状态（刹车指示）
                                     //3 尾灯闪烁状态
                                     //4~7 保留
    uint32_t fan_work           : 1; //0 风扇关闭状态     1 风扇开启状态
    uint32_t brake              : 1; //0 非制动状态       1 制动状态
    uint32_t slow_down          : 1; //0 非减速状态       1 减速状态（和刹车指示灯同步，但不一定是制动状态）
    uint32_t dfu_state          : 1; //0 无固件升级       1 有设备在固件升级中
    uint32_t reserve            : 5; //保留
  }GNUC_PACKED VX_STATE;
*/

// Lorin 实时状态
abstract class LorinRealtimeStatus extends RealtimeStatusBase {
  // 字段定义
  int hmicRunMode = 0; // 0 失能状态 1 工作状态 2 休眠状态 3 锁车状态
  int mcRunMode =
      0; // 0 正常失能状态 1 正常平衡状态 2 保护翘板状态 3 保护失能状态 4 电机锁死状态 5 空载保护状态 6 负载检测状态 7 辅助平衡状态
  bool motorWork = false; // 0 电机在非工作状态 1 电机在工作状态
  bool chargeState = false; // 0 非充电状态 1 充电状态
  bool backupBattery = false; // 0 备用电池未接入 1 备用电池已接入
  int chargePortDetect =
      0; // 0 无任何设备接入 1 充电器插入 2 备用电池输出口插入 3 另一台车的直流输出口接入 4 不能识别的设备
  bool chargePortOn = false; // 0 充电口关闭状态 1 充电口开启状态
  int dcPortDetect = 0; // 0 无任何设备接入 1 逆变器插入 2 备用电池充电口插入 3 另一台车的充电口接入 4 不能识别的设备
  bool dcOutputEnable = false; // 0 直流输出口关闭 1 直流输出口开启
  bool lampState = false; // 0 照明灯关闭状态 1 照明灯开启状态
  bool decorativeLight = false; // 0 装饰灯关闭状态 1 装饰灯开启状态
  bool lifted = false; // 0 提手未触发状态 1 提手触发状态
  int tailLight = 0; // 0 尾灯关闭状态 1 尾灯低亮状态 2 尾灯高亮状态（刹车指示） 3 尾灯闪烁状态 4~7 保留
  bool fanWork = false; // 0 风扇关闭状态 1 风扇开启状态
  bool brake = false; // 0 非制动状态 1 制动状态
  bool slowDown = false; // 0 非减速状态 1 减速状态（和刹车指示灯同步，但不一定是制动状态）
  bool dfuState = false; // 0 无固件升级 1 有设备在固件升级中
  int reserve = 0; // 保留

  // 从字节数据解析
  LorinRealtimeStatus.fromBytes(Uint8List bytes) : super.fromBytes(bytes) {
    if (bytes.length < minLength) {
      throw ArgumentError(
          '字节数组长度不足，无法解析 $runtimeType，期望长度至少为 $minLength，实际长度为 ${bytes.length}');
    }
    var byteData = ByteData.sublistView(bytes);
    int offset = 0;
    int byte1 = byteData.getInt8(offset);
    hmicRunMode = BitUtils.getBits(byte1, 0, 3);
    mcRunMode = BitUtils.getBits(byte1, 3, 3);
    motorWork = BitUtils.isBitOne(byte1, 6);
    chargeState = BitUtils.isBitOne(byte1, 7);

    offset += 1;
    int byte2 = byteData.getInt8(offset);
    backupBattery = BitUtils.isBitOne(byte2, 0);
    chargePortDetect = BitUtils.getBits(byte2, 1, 3);
    chargePortOn = BitUtils.isBitOne(byte2, 4);
    dcPortDetect = BitUtils.getBits(byte2, 5, 3);

    offset += 1;
    int byte3 = byteData.getInt8(offset);
    dcOutputEnable = BitUtils.isBitOne(byte3, 0);
    lampState = BitUtils.isBitOne(byte3, 1);
    decorativeLight = BitUtils.isBitOne(byte3, 2);
    lifted = BitUtils.isBitOne(byte3, 3);
    tailLight = BitUtils.getBits(byte3, 4, 3);
    fanWork = BitUtils.isBitOne(byte3, 7);

    offset += 1;
    int byte4 = byteData.getInt8(offset);
    brake = BitUtils.isBitOne(byte4, 0);
    slowDown = BitUtils.isBitOne(byte4, 1);
    dfuState = BitUtils.isBitOne(byte4, 2);
  }

  // 将对象转换为字节数据
  @override
  Uint8List toBytes() {
    var byteData = ByteData(4);
    int byte1 = BitUtils.setBits(0, 0, 2, hmicRunMode) |
        BitUtils.setBits(0, 3, 5, mcRunMode) |
        BitUtils.setBit(6, motorWork) |
        BitUtils.setBit(7, chargeState);
    byteData.setInt8(0, byte1);

    int byte2 = BitUtils.setBit(0, backupBattery) |
        BitUtils.setBits(0, 1, 3, chargePortDetect) |
        BitUtils.setBit(4, chargePortOn) |
        BitUtils.setBits(0, 5, 7, dcPortDetect);
    byteData.setInt8(1, byte2);

    int byte3 = BitUtils.setBit(0, dcOutputEnable) |
        BitUtils.setBit(1, lampState) |
        BitUtils.setBit(2, decorativeLight) |
        BitUtils.setBit(3, lifted) |
        BitUtils.setBits(0, 4, 6, tailLight) |
        BitUtils.setBit(7, fanWork);
    byteData.setInt8(2, byte3);

    int byte4 = BitUtils.setBit(0, brake) |
        BitUtils.setBit(1, slowDown) |
        BitUtils.setBit(2, dfuState) |
        BitUtils.setBits(0, 3, 7, reserve);
    byteData.setInt8(3, byte4);

    return byteData.buffer.asUint8List();
  }

  // 将对象转换为Map
  @override
  Map<String, dynamic> toMap() {
    return {
      'hmic_run_mode': hmicRunMode,
      'mc_run_mode': mcRunMode,
      'motor_work': motorWork ? 1 : 0,
      'charge_state': chargeState ? 1 : 0,
      'backup_battery': backupBattery ? 1 : 0,
      'charge_port_detect': chargePortDetect,
      'charge_port_on': chargePortOn ? 1 : 0,
      'dc_port_detect': dcPortDetect,
      'dc_output_enable': dcOutputEnable ? 1 : 0,
      'lamp_state': lampState ? 1 : 0,
      'decorative_light': decorativeLight ? 1 : 0,
      'lifted': lifted ? 1 : 0,
      'tail_light': tailLight,
      'fan_work': fanWork ? 1 : 0,
      'brake': brake ? 1 : 0,
      'slow_down': slowDown ? 1 : 0,
      'dfu_state': dfuState ? 1 : 0,
      'reserve': reserve,
    };
  }

  @override
  int dataIntValue() {
    return Utils.computeDataIntVal(toBytes());
  }

  @override
  int dataLength() {
    return toBytes().length;
  }

  @override
  int get minLength => 4;
}
